package atguigu.thread.excutor;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.stream.Collectors;


public class ThreadDemo {
	
	public static void main(String[] args) {
		
		
		
		test7();
	}
	
	public static void test1() {
		// 1. 创建线程池
		ExecutorService es3 = Executors.newFixedThreadPool(3);
		List<Integer> list = Arrays.asList(1, 2, 3);
        List<Future<String>> futures = new ArrayList<>();
        for (Integer key : list) {
            // 2. 提交任务
            Future<String> future = es3.submit(() -> {
                // 睡眠一秒，模仿处理过程
                Thread.sleep(1000L);
                return "结果" + key;
            });
            futures.add(future);
        }

        // 3. 获取结果
        for (Future<String> future : futures) {
            try {
                String result = future.get();
                System.out.println(result);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        es3.shutdown();
	}
	
	public static void test2() {
		// 1. 创建线程池
        ExecutorService executorService = Executors.newFixedThreadPool(3);

        List<Integer> list = Arrays.asList(1, 2, 3);
        for (Integer key : list) {
            // 2. 提交任务
            CompletableFuture.supplyAsync(() -> {
                // 睡眠一秒，模仿处理过程
                try {
                    Thread.sleep(1000L);
                } catch (InterruptedException e) {
                }
                return "结果" + key;
            }, executorService).whenCompleteAsync((result, exception) -> {
                // 3. 获取结果
                System.out.println(result);
            });;
        }

        executorService.shutdown();
        // 由于whenCompleteAsync获取结果的方法是异步的，所以要阻塞当前线程才能输出结果
        try {
            Thread.sleep(2000L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
	}
	
	public static void test3() {
		
		List<Integer> rs = new ArrayList<Integer>();
		
		// 1. 创建线程池
        ExecutorService executorService = Executors.newFixedThreadPool(3);

        List<Integer> list = Arrays.asList(1, 2, 3);
        for (Integer key : list) {
            // 2. 提交任务
            CompletableFuture.supplyAsync(() -> {
                // 睡眠一秒，模仿处理过程
                try {
                    Thread.sleep(1000L);
                } catch (InterruptedException e) {
                }
                return key;
            }, executorService).whenCompleteAsync((result, exception) -> {
                // 3. 获取结果
            	rs.add(result);
            });;
        }

        executorService.shutdown();
        
        
        // 由于whenCompleteAsync获取结果的方法是异步的，所以要阻塞当前线程才能输出结果
        try {
            Thread.sleep(2000L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        int r = 0;
        for (Integer i : rs) {
			r += i;
		}
        System.out.println(r);
	}
	
	public static void test4() {
		// 1. 创建线程池
	    ExecutorService executorService = Executors.newFixedThreadPool(3);
	
	    List<Integer> list = Arrays.asList(1, 2, 3);
	    // 2. 提交任务
	    List<String> results = list.stream().map(key ->
	            CompletableFuture.supplyAsync(() -> {
	                // 睡眠一秒，模仿处理过程
	                try {
	                    Thread.sleep(1000L);
	                } catch (InterruptedException e) {
	                	
	                }
	                return "结果" + key;
	            }, executorService))
	            .map(CompletableFuture::join).collect(Collectors.toList());
	
	    executorService.shutdown();
	    // 3. 获取结果
	    System.out.println(results);
	}
	
	
	public static void test5() {
		// 1. 创建线程池
	    ExecutorService executorService = Executors.newFixedThreadPool(3);
	
	    // 2. 提交任务
	    List<Integer> list = Arrays.asList(1, 2, 3);
	    List<CompletableFuture<String>> list2 = new ArrayList<CompletableFuture<String>>();
	    
	    for (Integer key : list) {
	    	 CompletableFuture<String> supplyAsync = CompletableFuture.supplyAsync(() -> {
	                // 睡眠一秒，模仿处理过程
	                try {
	                    Thread.sleep(1000L);
	                } catch (InterruptedException e) {
	                }
	                return "结果" + key;
	            }, executorService);
            list2.add(supplyAsync);
		}
	    
	    List<String> collect = list2.stream().map(CompletableFuture::join).collect(Collectors.toList());
	
	    executorService.shutdown();
	    // 3. 获取结果
	    System.out.println(collect);
	}
	
	public static void test6() {
		// 1. 创建线程池
        ExecutorService executorService = Executors.newFixedThreadPool(3);
        List<Integer> list = Arrays.asList(1, 2, 3);
        
        // 2. 提交任务，并调用join()阻塞等待所有任务执行完成
        CompletableFuture.allOf(
        	list.stream().map(key ->CompletableFuture.runAsync(() -> {
	                // 睡眠一秒，模仿处理过程
	                try {
	                    Thread.sleep(1000L);
	                } catch (InterruptedException e) {
	                    
	                }
	                System.out.println("结果" + key);
                }, executorService)).toArray(CompletableFuture[]::new)).join();
        executorService.shutdown();
	}
	
	public static void test7() {
		// 1. 创建线程池
        ExecutorService executorService = Executors.newFixedThreadPool(3);

        List<Integer> list = Arrays.asList(1, 2, 3);
        long start = System.currentTimeMillis();
        
        // 2. 提交任务
        CompletableFuture<Object> completableFuture = CompletableFuture.anyOf(
            list.stream().map(key ->
	          CompletableFuture.supplyAsync(() -> {
	              // 睡眠一秒，模仿处理过程
	              try {
	                  Thread.sleep(1000L);
	              } catch (InterruptedException e) {
	              }
	              return "结果" + key;
	          }, executorService))
            .toArray(CompletableFuture[]::new));
        executorService.shutdown();

        // 3. 获取结果
        System.out.println(completableFuture.join());
	}
}
